/**
 *******************************************************************************
 * @FileName  : cmac.h
 * @Author    : GaoQiu
 * @CreateDate: 2020-05-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */

#ifndef CMAC_H_
#define CMAC_H_

#include "utils/defs_types.h"

#define AES_CMAC_TEST_EN   0

#define AES_BLOCK_SIZE     16
#define AES_CMAC_PADDING   0x80

/*! CMAC error code. */
enum{
	CMAC_SUCCESS             = 0,
	CMAC_ERR_INVALID_PARAM   = 1,
	CMAC_ERR_AES_KEY_INVALID = 2,
	CMAC_ERR_MAC_FAILED      = 3,
};

/*! CMAC Context Control Block. */
typedef struct{
	uint8_t  *key;                   /*! AES Key */
	uint8_t   k1[AES_BLOCK_SIZE];    /*! AES-CMAC subKey K1 */
	uint8_t   k2[AES_BLOCK_SIZE];    /*! AES-CMAC subKey K2 */
	uint8_t   iv[AES_BLOCK_SIZE];    /*! AES-CMAC subKey iv */
	uint8_t   cache[AES_BLOCK_SIZE];
	uint8_t   offset;
}CmacCtx_t;

/**
 * @brief  : Initialize CMAC Context Control Block.
 * @param  : pCtx     Pointer point to CMAC Context Control Block.
 * @param  : key      Pointer point to AES KEY buffer. big-endian
 * @return : none.
 */
uint8_t CMAC_InitContext(CmacCtx_t *pCtx, uint8_t *key);

/**
 * @brief  : Initialize CMAC Context Control Block.
 * @param  : pCtx     Pointer point to CMAC Context Control Block.
 * @param  : pData    Pointer point to data buffer.
 * @param  : len      the length of data.
 * @return : none.
 */
uint8_t CMAC_GenerateMac(CmacCtx_t *pCtx, uint8_t *pData, uint32_t len);

uint8_t CMAC_Final(uint8_t *pTag, CmacCtx_t *pCtx);

#if AES_CMAC_TEST_EN
void CMAC_Test(void);
#endif

#endif /* CMAC_H_ */
